﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;

namespace ClimateChangeChampionsData
{
      

    /*public class SortedList<T> : IQueryable<T>
    {
        public delegate Expression<bool> GetSort(string field);

        public SortedList(IQueryable<T> source, string sortExpression, GetSort del)
        {
            if (source == null)
            {
                throw new ArgumentNullException("source", "Source cannot be null");
            }
            _List = source;
            if (!string.IsNullOrEmpty(sortExpression))
            {
                Dictionary<string, bool> sorts = GetSorts(sortExpression);
                foreach(string key in sorts.Keys)
                {
                    if (sorts[key])
                        _List = source.OrderByDescending(Expression<>del.Invoke(key));
                    else
                        _List = source.OrderBy(del.Invoke(key));
                }
            }
        }

        private Dictionary<string, bool> GetSorts(string sortExpression)
        {
            bool overAllDesc = false;
            if (sortExpression.StartsWith("(", StringComparison.InvariantCultureIgnoreCase))
            {
                overAllDesc = true;
                sortExpression = sortExpression.Substring(1, sortExpression.LastIndexOf(")", StringComparison.InvariantCultureIgnoreCase) - 1);
            }

            Dictionary<string, bool> sorts = new Dictionary<string, bool>();
            string[] sortParts = sortExpression.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
            foreach (string sort in sortParts)
            {
                string tmpSort = sort.Trim();
                bool tmpDesc = false;
                if (sort.EndsWith(" desc", StringComparison.InvariantCultureIgnoreCase))
                {
                    tmpSort = sort.Substring(0, sort.Length - 5).Trim();
                    tmpDesc = true;
                }
                else if (sort.EndsWith(" asc", StringComparison.InvariantCultureIgnoreCase))
                {
                    tmpSort = sort.Substring(0, sort.Length - 4).Trim();
                    tmpDesc = true;
                }
                if (overAllDesc)
                    tmpDesc = !tmpDesc;
                sorts.Add(tmpSort, tmpDesc);
            }
            return sorts;

        }

        private IQueryable<T> _List;

        #region IEnumerable<T> Members

        public IEnumerator<T> GetEnumerator()
        {
            return _List.GetEnumerator();
        }

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return _List.GetEnumerator();
        }

        public Type ElementType
        {
            get { return _List.ElementType; }
        }

        public System.Linq.Expressions.Expression Expression
        {
            get { return _List.Expression; }
        }

        public IQueryProvider Provider
        {
            get { return _List.Provider; }
        }

    }*/

    public static class Sorting
    {
        public static IQueryable<TEntity> OrderBy<TEntity>(this IQueryable<TEntity> source, string sortExpression) where TEntity : class  
        {  
            var type = typeof(TEntity);  
            // Remember that for ascending order GridView just returns the column name and for descending it returns column name followed by DESC keyword  
            // Therefore we need to examine the sortExpression and separate out Column Name and order (ASC/DESC)  
            string[] expressionParts = sortExpression.Split(' '); // Assuming sortExpression is like [ColoumnName DESC] or [ColumnName]  
            string orderByProperty = expressionParts[0];  
            string sortDirection = "ASC";  
            string methodName = "OrderBy";  
   
            //if sortDirection is descending  
            if (expressionParts.Length > 1 && expressionParts[1] == "DESC")  
            {  
                 sortDirection = "Descending";  
                 methodName += sortDirection; // Add sort direction at the end of Method name  
             }  
             var property = type.GetProperty(orderByProperty);  
             var parameter = Expression.Parameter(type, "p");  
             var propertyAccess = Expression.MakeMemberAccess(parameter, property);  
             var orderByExp = Expression.Lambda(propertyAccess, parameter);  
             MethodCallExpression resultExp = Expression.Call(typeof(Queryable), methodName,  
                             new Type[] { type, property.PropertyType },  
                             source.Expression, Expression.Quote(orderByExp));
             return (IQueryable<TEntity>) source.Provider.CreateQuery(resultExp);  
         }  
         
        //public static SortedList<T> ToSortedList<T>(this IQueryable<T> source, string sortEspression)
        //{
        //    return new SortedList<T>(source, sortEspression);
        //}
    }
}
